/*
 * Statistics.java
 * 
 * Maintains both MIDI information dump from DumpReceiver and statistics from Analyze.java
 */

/*
 * Copyright (c) 2011 by Ryan Nikolaidis
 * All rights reserved.
 *
 */

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;


public class Statistics {

	public String[] artists=new String[0];
	public int selectedArtist = 0;
	public int[][] pitch=new int[1][1];
	public int[][] volume=new int[1][1];
	public int[][] onset=new int[1][1];
	public int[][] duration=new int[1][1];
	
//	generative
	public int[] histo_dur=new int[960]; // row number indicates the duration in 480 PPQ (max 20 quarter notes long)
	public double[] histo_norm_dur=new double[960]; // normalized version of histo_dur
	public int[] histo_pch=new int[128]; // absolute pitch
	public double[] histo_norm_pch=new double[128];
	

	
//	transformative
	public double[] octaveDispArray = {1, .1, .1, 1., 1., .1, .1, .1, .1, .1, .1, .1}; // which note could trigger an octave displacement on next note
	public double octaveDisp = .5;
	public double octaveDispUp = 0.;
	public double altOutline1 = .5;
	public double[] passingTonesArray = {.5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5}; // odds that a chunk uses passing tones
	public double passingTones = .5; // odds that a given relative pitch class is preceded by a passing tone
	public double passingTonesChromatic = .0; // probability that the passing tone will be chromatic 
	public int scale = 0;
	public double approachToneAbove = .5;
	public double approachToneDiatonic = 1;
	public int count;

//	song statistics
	public int meter = 4;
	public int PPQ = 480;
	public int TPB = 1920; // ticks per bar 
	public int lastBar = -1;
	public int key=7;
	public boolean isMinor=false;
	
// 	reference chord sequence

	public int[] chordRoots = 	{	2, 	7, 	0, 	0, 	4, 	9, 	2, 	7, 	0, 	5, 	0, 	4, 	9, 	6, 	11, 	4, 	11, 	4, 	9, 	2, 	7, 	0, 	0, 	4, 	9, 	2, 	7, 	0, 	5, 	6, 	0, 	5, 	4, 	9, 	2, 	7, 	0, 	0,};
	public int[] chordQualities = {		1161, 	1169, 	2193, 	2193, 	1097, 	1169, 	1161, 	1169, 	2193, 	2193, 	2193, 	1169, 	1161, 	1097, 	1169, 	1161, 	1169, 	1161, 	1169, 	1161, 	1169, 	2193, 	2193, 	1097, 	73, 	1161, 	1169, 	2193, 	2193, 	73, 	2193, 	2098321, 	1097, 	1169, 	1161, 	1169, 	2193,	2193 };
	public int[] chordDurations = {		192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	96,	96,	96,	96,	96,	96,	192,	192,	192,	192,	192,	192,	192,	192,	192,	96,	96,	96,	96,	96,	96,	192,	192,	192,	192,};
	//	revised score

	public int[] chordRoots2 = 	{	2, 	7, 	0, 	0, 	4, 	9, 	2, 	7, 	0, 	5, 	0, 	4, 	9, 	6, 	11, 	4, 	11, 	4, 	9, 	2, 	7, 	0, 	0, 	4, 	9, 	2, 	7, 	0, 	5, 	6, 	0, 	5, 	4, 	9, 	2, 	7, 	0, 	0,};
	public int[] chordQualities2 = {		1161, 	1169, 	2193, 	2193, 	1097, 	1169, 	1161, 	1169, 	2193, 	2193, 	2193, 	1169, 	1161, 	1097, 	1169, 	1161, 	1169, 	1161, 	1169, 	1161, 	1169, 	2193, 	2193, 	1097, 	73, 	1161, 	1169, 	2193, 	2193, 	73, 	2193, 	2098321, 	1097, 	1169, 	1161, 	1169, 	2193,	2193 };
	public int[] chordDurations2 = {		192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	192,	96,	96,	96,	96,	96,	96,	192,	192,	192,	192,	192,	192,	192,	192,	192,	96,	96,	96,	96,	96,	96,	192,	192,	192,	192,};
	
	public void receive(int p, int velocity, int dur){

	}
	
	public void init() 
	{
		pitch=new int[1][1];
		volume=new int[1][1];
		onset=new int[1][1];
		duration=new int[1][1];
	}
	
	  public void saveArray(String filename, int[][] output_veld) {
	     try {
	        FileOutputStream fos = new FileOutputStream(filename);
	        GZIPOutputStream gzos = new GZIPOutputStream(fos);
	        ObjectOutputStream out = new ObjectOutputStream(gzos);
	        out.writeObject(output_veld);
	        out.flush();
	        out.close();
	     }
	     catch (IOException e) {
	         System.out.println(e); 
	     }
	  }

	  public int[][] loadArray(String filename) {
	      try {
	        FileInputStream fis = new FileInputStream(filename);
	        GZIPInputStream gzis = new GZIPInputStream(fis);
	        ObjectInputStream in = new ObjectInputStream(gzis);
	        int[][] gelezen_veld = (int[][])in.readObject();
	        in.close();
	        return gelezen_veld;
	      }
	      catch (Exception e) {
	          System.out.println(e);
	      }
	      return null;
	  }
//	  send array of probabilities and it selects one
		public static int sel(double[] prob)
		{
			int[] intArray = new int[prob.length];
			for (int i=0;i<prob.length;i++)
			{
				intArray[i]=(int) (prob[i]*10000.);
			}
			int sum = 0;
			for (int i=0;i<prob.length;i++)
			{
				sum=sum+intArray[i];
			}
			int indexSel=(int) (Math.random()*sum);
			int i=0;
			int index=0;
			while (indexSel>i&&index<intArray.length)
			{
				i = i+intArray[index];
				index++;
			}
			int selection = index-1;
			
			System.out.println("selection = "+selection);
			
			return selection;
		}
}